''''''
import re

import jsonpath

'''
定义一个类
1、定义初始化方法
    1、1获取所有的测试用例，绑定为实例属性
2、定义一个方法，根据当前的id，执行前置用例替换依赖字段，进行接口请求
    2、1获取用于判断当前用例的接口是否有依赖的关键字段，value，header，rely，caseid
    2.2判断：当前用例是否有依赖（rely是否为y），（caseid是否有值）：
        2.2.1解决依赖：根据正则表达式找出请求头或请求体里面依赖的字段：可以单独封装一个方法
        2、2、2执行依赖的前置用例，得到前置用例的相应结果res，在请求结果内根据上一步得到的依赖字段获取实际的结果：可以单独封装一个方法
        2.2.3上衣获取到的依赖子弹的实际结果，替换原来的{$xx}的内容
        2.2.4用替换后的数据进行当前接口的请求，并返回请求后的相应对象
    2.3否，没有依赖，直接进行接口请求，并返回请求后的相应对象
'''
from common.configHttp import ConfigHttp
from common.log import log
logger = log()

# 定义一个类
class PreSolve:
    # 1、定义初始化方法
    def __init__(self, data):
        # 1、1获取所有的测试用例，绑定为实例属性
        self.test_data = data

    # 2、定义一个方法，根据当前的id，执行前置用例替换依赖字段，进行接口请求
    def pre_solve(self, dic):
        # 2、1获取用于判断当前用例的接口是否有依赖的关键字段，value，header，rely，caseid
        value, header, rely, caseid = dic['value'], dic['header'], dic['rely'], dic['caseid']
        # 2.2判断：当前用例是否有依赖（rely是否为y），（caseid是否有值）：
        if rely == 'y' and caseid != '':
            # 2.2.1解决依赖：根据正则表达式找出请求头或请求体里面依赖的字段：可以单独封装一个方法
            goal_h=self.__get_predata(header)
            goal_b=self.__get_predata(value)
            logger.debug(f'头里面的依赖字段{goal_h},请求体里的依赖字段{goal_b}')
        # 2、2、2执行依赖的前置用例，得到前置用例的相应结果res，在请求结果内根据上一步得到的依赖字段获取实际的结果：可以单独封装一个方法
            h,b=self.__run_pre(caseid,goal_h,goal_b)
            logger.debug(f'头里面的实际数据是{h},请求体里面的实际数据是{b}')
        # 2.2.3上一步获取到的依赖子弹的实际结果，替换原来的{$xx}的内容
            logger.debug(f'替换前的数据{dic}')
            if h !=None:
                dic['header']=header.replace('${'+goal_h+'}',h)
            if b !=None:
                dic['value']=value.replace('${'+goal_b+'}',b)
            logger.debug(f'替换后的数据{dic}')
            ch= ConfigHttp(dic)
            res=ch.run()
            return res
        # 2.2.4用替换后的数据进行当前接口的请求，并返回请求后的相应对象
        # 2.3否，没有依赖，直接进行接口请求，并返回请求后的相应对象
        else:
            res = ConfigHttp(dic).run()
            return res

    # 定义一个方法，根据需求提取出请求头、请求体力的依赖字段
    @staticmethod
    def __get_predata(a):
        # 根据正则表达式，获取出来需要依赖字段的变量名
        res = re.findall(r'\${(.*?)}', a)
        # 判断获取出来的值是否为0
        if len(res) != 0:
            # 是0就可以正常返回这个数据。一般返回的只有一个值，所以这里正则表达式书写要准确
            return res[0]

    def __run_pre(self, caseid, goal_header=None, goal_body=None):
        # 准备前置接口请求需要的数据,针对的是caseid单独写出来的测试用例
        data = self.test_data[int(caseid) - 1]
        # 调用公共方法，执行第一个接口的请求
        # ch = ConfigHttp(data)
        # res = ch.run()
        # 优化调用方法，如果是前面还有其他的接口有依赖，这里直接可以使用类似递归的方式调用自己本身的方法。
        res=self.pre_solve(data)
        # 根据提供的参数，判断是否需要进行依赖字段，如果有依赖字段的值，那么久返回依赖字段并从实际请求结果中获取到对应的值，如果没有返回None
        if goal_header != None:
            goal_header = res.headers[goal_header]
        if goal_body != None:
            goal_body = jsonpath.jsonpath(res.json(), f'$..{goal_body}')[0]
        # 最后返回给外界需要调用的依赖的值
        return goal_header, goal_body


if __name__ == '__main__':
    from common.readData import ReadData

    rd = ReadData()
    data = rd.read_excel(2)
    ps = PreSolve(data)
    # 调试第一个方法
    # res=ps.pre_solve(data[0])
    # print(res.text)
    res2=ps.pre_solve(data[4])
    print(res2.text)
    # str1 = "{'name':'${username}','link':'www.baidu.com'}"
    # str2 = '{"cookie":"${Set-Cookie}"}'
    # str3 = "{'username':'liangchao','password':'123456'}"
    # print(ps.get_predata(str1))
    # print(ps.get_predata(str2))
    # print(ps.get_predata(str3))
    # print(ps.run_pre("1"))
    # print(ps.run_pre("1", goal_header="Set-Cookie"))
    # print(ps.run_pre("1", "Set-Cookie", "username"))
